
package doc2db.fileWorker;

import doc2db.Keey;
import doc2db.table.*;
import java.util.List;
import java.util.ArrayList;
import javax.swing.JOptionPane;

/**
 *
 * @author yura
 */
public class RefactorTable {
    /**список таблиц*/
    private List<DocTable> tables ;
    /**for super refactoring NOT USED
    /**первая часть названия заголовка при добовлении пустых колоноу*/
    private String headName = "doc2dbHead";

    /**
     * creatr new instances
     * @param tables tale list
     */
    public RefactorTable(List<DocTable> tables) {
        this.tables = tables;
    }

    /**
     *  Преобразование таблиц к необходимому формату<br>
     *  Полследовательностть действий:<ol>
     *      <li>если необходимо, разбивает объеденённые ячейки</li>
     *      <li>превращение таблици в правельную таблицу (для ДБ)</li>
     *      <li>обьеденение одинаковых таблицы, переправление полей таблици</li>
     *  </ol>
     */
    public void refactor() {

        if (Keey.isTreeHead) {
            RefactorDublicateLongCell r = new RefactorDublicateLongCell(tables);
            r.refactoDublicateLongCell();
        }

        refactorAddSameTableIntoWan();

        refactorAddEmptyCell();

    //refactorCreateReturnTables();

    }

    /**
     *  Превращение таблицы в правильную таблицу (для ДБ)
     */
    private void refactorAddEmptyCell() {
        int maxCellAll = 1;
        int[] maxCell = new int[tables.size()];

        //узнаём необходимое количество стоббцов таблици
        int j = 0;
        for (DocTable tb : tables) {
            int NumCell = 1;
            for (int i = 0; i < tb.getBody().size(); i++) {
                if (tb.getBody().getRowsSize(i) > NumCell) {
                    NumCell = tb.getBody().getRowsSize(i);
                }
            }
            if (NumCell < tb.getHead().get().length) {
                NumCell = tb.getHead().get().length;
            }
            maxCell[j] = NumCell;
            if(maxCellAll < NumCell){
                maxCellAll = NumCell;
            }
            j++;
        }

        //создаём неодостающие заголовки
        int jj = 0;
        for (DocTable tb : tables) {
            //System.out.println(Keey.isUniteTables);
            if(Keey.isUniteTables){
               maxCell[jj] = maxCellAll;
            }
            int k = 0;
            while (maxCell[jj] > tb.getHead().get().length) {
                System.err.println("adding kell - probebly error in template!!!");
                tb.addHeadCell(headName + k++);
            }
            jj++;
        }

        //заполняем незаполненные ячейки таблици
        for (DocTable tb : tables) {
            for (int i = 0; i < tb.getBody().size() -1; i++) {
                for (int l = 0; l < tb.getBody().getRows(i).size(); l++) {
                    if(tb.getBody().getRows(i).get(l).equals("")){
                        tb.getBody().getRows(i).set(l, "_");
                    }
                }
            }
            for (int i = 0; i < tb.getBody().size() -1; i++) {
                List<String> filledHead = new ArrayList<String>();
                for (int l = 0; l < tb.getBody().getRows(i).size(); l++) {
                    filledHead.add(tb.getBody().getRows(i).getCellHead(l));
                }
                for (int l = 0; l < tb.getHead().getSize(); l++) {
                    if (f1(filledHead, tb.getHead().get(l).getName())) {
                        tb.getBody().getRows(i).add("-", tb.getHead().get(l).getName());
                    }
                }
            }
        }

    }

    /**
     *  Объединение одинаковых таблиц
     */
    private void refactorAddSameTableIntoWan() {
        if (!Keey.isUniteTables || tables.size() < 2) {
            return;
        }

        for (int i = 1; i < tables.size(); i++) {
            for(int j = 0 ; j < tables.get(i).getHead().getSize() ; j++){
                if( f1(tables.get(0).getHead().get(), tables.get(i).getHead().get()[j])){
                    tables.get(0).addHeadCell(tables.get(i).getHead().get(j));
                }
            }
        }

        this.checkHeadType();
        
        for (int i = 1 ; i < tables.size() ; i++) {
            for(int j = 0 ; j < tables.get(i).getBody().size() - 1 ; j++){
                for(int k = 0 ; k < tables.get(i).getBody().getRows(j).size() ; k++){
                    tables.get(0).addBodyCell(tables.get(i).getBody().getRows(j).getCell(k));
                }
                tables.get(0).addNewRow();
            }
        }

        int sz = tables.size();
        for (int i = 1 ; i < sz ; i++) {
            tables.remove(tables.size() - 1);
        }
    }

    /**
     * Chec data type in appendings tablse
     */
    private void checkHeadType() {
        List<String> l = new ArrayList<String>();
        
        String name = "";
        String type = "";
        boolean nedChange = false;
        for(int iter = 0 ; iter < tables.get(0).getHead().getSize() - 1 ; iter++){
            nedChange = false;
            l.clear();
            name = tables.get(0).getHead().get(iter).getName();
            type = tables.get(0).getHead().get(iter).getHead();

            for (int i = 1; i < tables.size(); i++) {
                for(int j = 0 ; j < tables.get(i).getHead().getSize() ; j++){
                    if(name.equals(tables.get(i).getHead().get(j).getName())){
                        if(!type.equals(tables.get(i).getHead().get(j).getHead())){
                            nedChange = true;
                            l.add(tables.get(i).getHead().get(j).getHead());
                        }
                    }
                }
            }
            
            if(nedChange){
                l.add(type);
                String [] cb = l.toArray(new String[0]);
                String s = (String) JOptionPane.showInputDialog(null,
                        "для заголовка '" + name + "'\nкакой тип данных выбрать?",
                        "doc2db - объединение таблиц", JOptionPane.PLAIN_MESSAGE,
                        null, cb, cb[0]);
                if ((s != null) && (s.length() > 0)) {
                    tables.get(0).getHead().get(iter).setHead(s);
                }
            }

        }
    }

    /**
     * Return false if s have now element equals s2
     * @param s array of data
     * @param s2 string
     * @return false if s have now element equals s2
     */
    private boolean f1 (String s[], String s2){
        for (int i = 0; i < s.length; i++) {
            if(s[i].equals(s2))
                return false;
        }
        return true;
    }

    /**
     * Return false if s have now element equals s2
     * @param s array of data
     * @param s2 string
     * @return false if s have now element equals s2
     */
    private boolean f1(List<String> s, String s2) {
        for (int i = 0; i < s.size(); i++) {
            if(s.get(i).equals(s2))
                return false;
        }
        return true;
    }

}
